package cn.bqjr.eily.redis.spring.boot.autoconfigure;


import cn.bqjr.eily.redis.spring.boot.serializer.RedisObjectSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;
import java.util.stream.Stream;

@Configuration
public class RedisAutoconfigure extends CachingConfigurerSupport {
    private Logger logger = LoggerFactory.getLogger(RedisAutoconfigure.class);
    /**
     * 初始化redis连接
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer()); //key序列化
        template.setValueSerializer(new RedisObjectSerializer()); //value序列化
        logger.debug("RedisTemplate init successful");
        return template;
    }

    /**
     * key序列化规则
     * @return
     */
    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return (Object target, Method method, Object... params) -> {
            StringBuilder sb = new StringBuilder()
                    .append(target.getClass().getName())
                    .append(method.getName());
            Stream.of(params).forEach(obj -> sb.append(obj.toString()));
            return sb.toString();
        };
    }

    /**
     * 初始化缓存管理器
     * @param redisTemplate
     * @param defaultExpiration
     * @return
     */
    @Bean
    public CacheManager cacheManager(
            RedisTemplate<Object, Object> redisTemplate,
            @Value("${spring.redis.defaultExpiration:1800}") long defaultExpiration) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setDefaultExpiration(defaultExpiration); //默认存活时间，秒
        cacheManager.setUsePrefix(true);
        logger.debug("Redis CacheManager init successful, defaultExpiration: {}", defaultExpiration);
        return cacheManager;
    }
}
